<script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue';
import {
  Card,
  Table,
  Button,
  Modal,
  Form,
  Input,
  InputNumber,
  Space,
  Tag,
  Switch,
  message,
} from 'ant-design-vue';
import type { TableColumnsType } from 'ant-design-vue';
import type { FormInstance } from 'ant-design-vue/es/form';
import { useRouter } from 'vue-router';

import {
  createTenantApi,
  getTenantsApi,
  updateTenantApi,
  updateTenantStatusApi,
  type TenantApi,
} from '#/api/core';

interface TenantTableRecord extends TenantApi.TenantRecord {}

const loading = ref(false);
const saving = ref(false);
const tenants = ref<TenantTableRecord[]>([]);
const statusLoadingId = ref<number | null>(null);

const isModalVisible = ref(false);
const isEditing = ref(false);
const currentTenantId = ref<number | null>(null);
const formRef = ref<FormInstance>();
const router = useRouter();

const initialAccountModalVisible = ref(false);
const initialAccountInfo = reactive({
  tenantName: '',
  username: '',
  plain_password: '',
  email: '' as string | null,
  phone: '' as string | null,
  combinedText: '',
});

const formState = reactive({
  name: '',
  company_name: '',
  tax_registration_number: '',
  address: '',
  bank_name: '',
  bank_account: '',
  contact_phone: '',
  contact_email: '',
  service_fee_rate: 0.05,
  tenant_type: 'enterprise' as TenantApi.TenantType,
});

const columns: TableColumnsType<TenantTableRecord> = [
  { title: 'ID', dataIndex: 'id', key: 'id', width: 80, sorter: true },
  { title: '租户名称', dataIndex: 'name', key: 'name', sorter: true, width: 200, ellipsis: true },
  { title: '公司名称', dataIndex: 'company_name', key: 'company_name', width: 220, ellipsis: true },
  { title: '税务登记号', dataIndex: 'tax_registration_number', key: 'tax_registration_number', width: 200, ellipsis: true },
  { title: '开户行名称', dataIndex: 'bank_name', key: 'bank_name', width: 200, ellipsis: true },
  { title: '开户行账号', dataIndex: 'bank_account', key: 'bank_account', width: 200, ellipsis: true },
  { title: '租户类型', dataIndex: 'tenant_type', key: 'tenant_type', width: 140 },
  { title: '联系电话', dataIndex: 'contact_phone', key: 'contact_phone', width: 140 },
  { title: '联系邮箱', dataIndex: 'contact_email', key: 'contact_email', width: 200 },
  { title: '服务费率', dataIndex: 'service_fee_rate', key: 'service_fee_rate', width: 120 },
  { title: '账户余额', dataIndex: 'account_balance', key: 'account_balance', width: 120, sorter: true },
  { title: '可开票金额', dataIndex: 'invoiceable_amount', key: 'invoiceable_amount', width: 120, sorter: true },
  { title: '状态', dataIndex: 'status', key: 'status', width: 120 },
  { title: '创建时间', dataIndex: 'created_at', key: 'created_at', width: 180, sorter: true },
  { title: '更新时间', dataIndex: 'updated_at', key: 'updated_at', width: 180, sorter: true },
  { title: '创建人', dataIndex: ['creator', 'name'], key: 'creator_name', width: 120 },
  { title: '操作', key: 'actions', fixed: 'right', width: 200 },
];

const fetchTenants = async () => {
  loading.value = true;
  try {
    const response = await getTenantsApi();
    tenants.value = response.items;
  } catch (error) {
    console.error('获取租户列表失败', error);
    message.error('获取租户列表失败');
  } finally {
    loading.value = false;
  }
};

const resetForm = () => {
  formState.name = '';
  formState.company_name = '';
  formState.tax_registration_number = '';
  formState.address = '';
  formState.bank_name = '';
  formState.bank_account = '';
  formState.contact_phone = '';
  formState.contact_email = '';
  formState.service_fee_rate = 0.05;
  formState.tenant_type = 'enterprise';
};

const resetInitialAccountInfo = () => {
  initialAccountInfo.tenantName = '';
  initialAccountInfo.username = '';
  initialAccountInfo.plain_password = '';
  initialAccountInfo.email = null;
  initialAccountInfo.phone = null;
  initialAccountInfo.combinedText = '';
  initialAccountModalVisible.value = false;
};

const openCreateModal = () => {
  isEditing.value = false;
  currentTenantId.value = null;
  resetForm();
  resetInitialAccountInfo();
  initialAccountModalVisible.value = false;
  isModalVisible.value = true;
};

const openEditModal = (record: TenantTableRecord) => {
  isEditing.value = true;
  currentTenantId.value = record.id;
  formState.name = record.name;
  formState.company_name = record.company_name ?? '';
  formState.tax_registration_number = record.tax_registration_number ?? '';
  formState.address = record.address ?? '';
  formState.bank_name = record.bank_name ?? '';
  formState.bank_account = record.bank_account ?? '';
  formState.contact_phone = record.contact_phone ?? '';
  formState.contact_email = record.contact_email ?? '';
  formState.service_fee_rate = Number(record.service_fee_rate);
  formState.tenant_type = record.tenant_type;
  initialAccountModalVisible.value = false;
  isModalVisible.value = true;
};

const goToTenantTasks = (record: TenantTableRecord) => {
  router.push({
    name: 'TenantTaskList',
    params: { tenantId: String(record.id) },
    query: { tenantName: record.name },
  });
};

const handleModalCancel = () => {
  isModalVisible.value = false;
  formRef.value?.resetFields();
  saving.value = false;
};

const openInitialAccountModal = (
  tenantName: string,
  account: TenantApi.TenantInitialAccount | null,
) => {
  if (!account) {
    return;
  }
  initialAccountInfo.tenantName = tenantName;
  initialAccountInfo.username = account.username;
  initialAccountInfo.plain_password = account.plain_password;
  initialAccountInfo.email = account.email ?? '';
  initialAccountInfo.phone = account.phone ?? '';
  const lines = [
    `租户：${tenantName}`,
    `用户名：${account.username}`,
    `初始密码：${account.plain_password}`,
    `邮箱：${account.email || '—'}`,
    `手机号：${account.phone || '—'}`,
  ];
  initialAccountInfo.combinedText = lines.join('\n');
  initialAccountModalVisible.value = true;
};


const submitForm = async () => {
  try {
    const values = await formRef.value?.validate();
    if (!values) return;

    saving.value = true;
    if (isEditing.value && currentTenantId.value) {
      await updateTenantApi(currentTenantId.value, values);
      message.success('租户信息已更新');
    } else {
      const response = await createTenantApi(values);
      message.success('租户创建成功');
      openInitialAccountModal(response.tenant.name, response.initial_account);
    }

    isModalVisible.value = false;
    await fetchTenants();
  } catch (error: any) {
    if (error?.errorFields) {
      return;
    }
    console.error('保存租户信息失败', error);
    message.error('保存租户信息失败');
  } finally {
    saving.value = false;
  }
};

const applyStatus = async (record: TenantTableRecord, status: TenantApi.TenantStatus) => {
  statusLoadingId.value = record.id;
  try {
    await updateTenantStatusApi(record.id, status);
    message.success(status === 'active' ? '租户已启用' : '租户已禁用');
    await fetchTenants();
  } catch (error) {
    console.error('更新租户状态失败', error);
    message.error('更新租户状态失败');
  } finally {
    statusLoadingId.value = null;
  }
};

const handleStatusToggle = (record: TenantTableRecord, checked: boolean) => {
  const nextStatus: TenantApi.TenantStatus = checked ? 'active' : 'inactive';
  if (!checked) {
    Modal.confirm({
      title: '确认禁用该租户？',
      content: `禁用后，租户 ${record.name} 的所有成员将立即退出登录并禁止访问。`,
      okText: '确认禁用',
      okType: 'danger',
      cancelText: '取消',
      onOk: () => applyStatus(record, nextStatus),
    });
  } else {
    applyStatus(record, nextStatus);
  }
};

const formatRate = (value: number) => `${(Number(value || 0) * 100).toFixed(2)}%`;
const formatCurrency = (value: number) =>
  new Intl.NumberFormat('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(
    Number(value || 0),
  );

const formatDateTime = (value?: string | null) => {
  if (!value) {
    return '-';
  }
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return value;
  }
  const pad = (num: number) => (num < 10 ? `0${num}` : `${num}`);
  const year = date.getFullYear();
  const month = pad(date.getMonth() + 1);
  const day = pad(date.getDate());
  const hours = pad(date.getHours());
  const minutes = pad(date.getMinutes());
  const seconds = pad(date.getSeconds());
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};

const resolveValue = (record: TenantTableRecord, dataIndex: any) => {
  if (Array.isArray(dataIndex)) {
    return dataIndex.reduce((acc: any, key: string | number) => (acc ? acc[key] : undefined), record);
  }
  return (record as Record<string, any>)[dataIndex as string];
};

onMounted(() => {
  fetchTenants();
});
</script>

<template>
  <div class="p-5">
    <Card title="租户管理" :bordered="false" class="mb-4">
      <template #extra>
        <Button type="primary" @click="openCreateModal">新增租户</Button>
      </template>
      <Table
        :columns="columns"
        :data-source="tenants"
        :loading="loading"
        row-key="id"
        :pagination="{ pageSize: 10 }"
        :scroll="{ x: 1800 }"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'tenant_type'">
            <Tag color="blue">{{ record.tenant_type === 'enterprise' ? '企业' : '个人' }}</Tag>
          </template>
          <template v-else-if="column.key === 'service_fee_rate'">
            <span>{{ formatRate(record.service_fee_rate) }}</span>
          </template>
          <template v-else-if="column.key === 'account_balance'">
            <span>¥{{ formatCurrency(record.account_balance) }}</span>
          </template>
          <template v-else-if="column.key === 'invoiceable_amount'">
            <span>¥{{ formatCurrency(record.invoiceable_amount) }}</span>
          </template>
          <template v-else-if="column.key === 'created_at'">
            <span>{{ formatDateTime(record.created_at) }}</span>
          </template>
          <template v-else-if="column.key === 'updated_at'">
            <span>{{ formatDateTime(record.updated_at) }}</span>
          </template>
          <template v-else-if="column.key === 'status'">
            <Tag :color="record.status === 'active' ? 'green' : 'gold'">
              {{ record.status === 'active' ? '启用' : '禁用' }}
            </Tag>
          </template>
          <template v-else-if="column.key === 'actions'">
            <Space>
              <Button type="link" size="small" @click="goToTenantTasks(record)">查看任务</Button>
              <Button type="link" size="small" @click="openEditModal(record)">编辑</Button>
              <Switch
                :checked="record.status === 'active'"
                :loading="statusLoadingId === record.id"
                checked-children="启用"
                un-checked-children="禁用"
                @change="checked => handleStatusToggle(record, Boolean(checked))"
              />
            </Space>
          </template>
          <template v-else>
            {{ resolveValue(record, column.dataIndex) ?? '--' }}
          </template>
        </template>
      </Table>
    </Card>

    <Modal
      v-model:open="isModalVisible"
      :title="isEditing ? '编辑租户' : '新增租户'"
      :confirm-loading="saving"
      @ok="submitForm"
      @cancel="handleModalCancel"
    >
      <Form ref="formRef" :model="formState" layout="vertical">
        <Form.Item
          label="租户名称"
          name="name"
          :rules="[{ required: true, message: '请输入租户名称' }]"
        >
          <Input v-model:value="formState.name" placeholder="请输入租户名称" />
        </Form.Item>
        <Form.Item
          label="公司名称"
          name="company_name"
          :rules="[{ required: false, message: '请输入公司名称' }]"
        >
          <Input v-model:value="formState.company_name" placeholder="请输入公司名称" />
        </Form.Item>
        <Form.Item
          label="税务登记号"
          name="tax_registration_number"
          :rules="[{ required: false, message: '请输入税务登记号' }]"
        >
          <Input
            v-model:value="formState.tax_registration_number"
            placeholder="请输入税务登记号"
          />
        </Form.Item>
        <Form.Item
          label="公司地址"
          name="address"
          :rules="[{ required: false, message: '请输入公司地址' }]"
        >
          <Input.TextArea
            v-model:value="formState.address"
            :rows="3"
            placeholder="请输入公司地址"
          />
        </Form.Item>
        <Form.Item
          label="开户行名称"
          name="bank_name"
          :rules="[{ required: false, message: '请输入开户行名称' }]"
        >
          <Input v-model:value="formState.bank_name" placeholder="请输入开户行名称" />
        </Form.Item>
        <Form.Item
          label="开户行账号"
          name="bank_account"
          :rules="[{ required: false, message: '请输入开户行账号' }]"
        >
          <Input v-model:value="formState.bank_account" placeholder="请输入开户行账号" />
        </Form.Item>
        <Form.Item
          label="联系电话"
          name="contact_phone"
          :rules="[{ required: true, message: '请输入联系电话' }]"
        >
          <Input v-model:value="formState.contact_phone" placeholder="请输入联系电话" />
        </Form.Item>
        <Form.Item
          label="联系邮箱"
          name="contact_email"
          :rules="[
            { required: true, message: '请输入联系邮箱' },
            { type: 'email', message: '请输入有效的邮箱地址' },
          ]"
        >
          <Input v-model:value="formState.contact_email" placeholder="请输入联系邮箱" />
        </Form.Item>
        <Form.Item
          label="服务费率"
          name="service_fee_rate"
          :rules="[{ required: true, message: '请输入服务费率' }]"
        >
          <InputNumber
            v-model:value="formState.service_fee_rate"
            :min="0"
            :max="1"
            :step="0.01"
            :precision="2"
            style="width: 100%"
            placeholder="请输入服务费率，范围0-1"
          />
        </Form.Item>
      </Form>
    </Modal>
    <Modal
      v-model:open="initialAccountModalVisible"
      title="初始账号信息"
      :footer="null"
      @close="resetInitialAccountInfo"
      @cancel="resetInitialAccountInfo"
    >
      <p class="initial-tip">
        已为租户 {{ initialAccountInfo.tenantName }} 自动生成首个账号信息，请复制后转交给租户管理员。
      </p>
      <Input.TextArea
        :value="initialAccountInfo.combinedText"
        readonly
        :rows="6"
        class="initial-textarea"
      />
    </Modal>
  </div>
</template>

<style scoped>
.initial-tip {
  margin-bottom: 12px;
  font-size: 14px;
  color: #64748b;
}


.initial-textarea :deep(.ant-input-textarea-show-count) {
  display: none;
}
</style>
